using System;
using bitzhuwei.Compiler;

namespace bitzhuwei.ExpFormat {
    partial class CompilerExp {
        /// <summary>
        /// <see cref="LRNode.kind"/> -&gt; <see cref="Action{LRNode, TContext{Exp}}"/>
        /// </summary>
        private static readonly Action<LRNode, TContext<Exp>>?[]
            @expExtractorItems = new Action<LRNode, TContext<Exp>>[1/*'¥'*/ + 3/*Vn*/];

        /// <summary>
        /// initialize dict for extractor.
        /// </summary>
        private static void InitializeExtractorItems() {
            var extractorItems = @expExtractorItems;

            #region obsolete
            //extractorDict.Add(st.NotYet,
            //(node, context) => {
            // not needed.
            //});
            //extractorDict.Add(st.Error,
            //(node, context) => {
            // nothing to do.
            //});
            //extractorDict.Add(st.blockComment,
            //(node, context) => {
            // not needed.
            //});
            //extractorDict.Add(st.inlineComment,
            //(node, context) => {
            // not needed.
            //});
            #endregion obsolete

            extractorItems[st.@终/*0*/] = static (node, context) => {
                // [-1] Exp' = Exp ;
                // dumped by ExternalExtractor
                var @final = (VnExp)context.rightStack.Pop();
                var left = new Exp(@final);
                context.result = left; // final step, no need to push into stack.
            }; // end of extractorItems[st.@终/*0*/] = (node, context) => { ... };
            const int lexiVtCount = 7;
            extractorItems[st.Exp枝/*8*/ - lexiVtCount] = static (node, context) => {
                System.Diagnostics.Debug.Assert(node.regulation != null);
                switch (node.regulation.index) {
                case 0: { // [0] Exp = Exp '+' Term ;
                    // dumped by ListExtractor 2
                    var r0 = (VnTerm)context.rightStack.Pop();
                    var r1 = (Token)context.rightStack.Pop();// reserved word is omissible
                    var r2 = (VnExp)context.rightStack.Pop();
                    var left = r2;
                    left.Add(r1, r0);
                    context.rightStack.Push(left);
                }
                break;
                case 1: { // [1] Exp = Exp '-' Term ;
                    // dumped by ListExtractor 2
                    var r0 = (VnTerm)context.rightStack.Pop();
                    var r1 = (Token)context.rightStack.Pop();// reserved word is omissible
                    var r2 = (VnExp)context.rightStack.Pop();
                    var left = r2;
                    left.Add(r1, r0);
                    context.rightStack.Push(left);
                }
                break;
                case 2: { // [2] Exp = Term ;
                    // dumped by ListExtractor 1
                    var r0 = (VnTerm)context.rightStack.Pop();
                    var left = new VnExp(r0);
                    context.rightStack.Push(left);
                }
                break;
                default: throw new NotImplementedException();
                }
            }; // end of extractorItems[st.Exp枝/*8*/ - lexiVtCount] = (node, context) => { ... };
            extractorItems[st.Term枝/*9*/ - lexiVtCount] = static (node, context) => {
                System.Diagnostics.Debug.Assert(node.regulation != null);
                switch (node.regulation.index) {
                case 3: { // [3] Term = Term '*' Factor ;
                    // dumped by ListExtractor 2
                    var r0 = (VnFactor)context.rightStack.Pop();
                    var r1 = (Token)context.rightStack.Pop();// reserved word is omissible
                    var r2 = (VnTerm)context.rightStack.Pop();
                    var left = r2;
                    left.Add(r1, r0);
                    context.rightStack.Push(left);
                }
                break;
                case 4: { // [4] Term = Term '/' Factor ;
                    // dumped by ListExtractor 2
                    var r0 = (VnFactor)context.rightStack.Pop();
                    var r1 = (Token)context.rightStack.Pop();// reserved word is omissible
                    var r2 = (VnTerm)context.rightStack.Pop();
                    var left = r2;
                    left.Add(r1, r0);
                    context.rightStack.Push(left);
                }
                break;
                case 5: { // [5] Term = Factor ;
                    // dumped by ListExtractor 1
                    var r0 = (VnFactor)context.rightStack.Pop();
                    var left = new VnTerm(r0);
                    context.rightStack.Push(left);
                }
                break;
                default: throw new NotImplementedException();
                }
            }; // end of extractorItems[st.Term枝/*9*/ - lexiVtCount] = (node, context) => { ... };
            extractorItems[st.Factor枝/*10*/ - lexiVtCount] = static (node, context) => {
                System.Diagnostics.Debug.Assert(node.regulation != null);
                switch (node.regulation.index) {
                case 6: { // [6] Factor = '(' Exp ')' ;
                    // dumped by DefaultExtractor
                    var r0 = (Token)context.rightStack.Pop();// reserved word is omissible
                    var r1 = (VnExp)context.rightStack.Pop();
                    var r2 = (Token)context.rightStack.Pop();// reserved word is omissible
                    var left = new VnFactor(r2, r1, r0);
                    context.rightStack.Push(left);
                }
                break;
                case 7: { // [7] Factor = 'number' ;
                    // dumped by DefaultExtractor
                    var r0 = (Token)context.rightStack.Pop();
                    var left = new VnFactor(r0);
                    context.rightStack.Push(left);
                }
                break;
                default: throw new NotImplementedException();
                }
            }; // end of extractorItems[st.Factor枝/*10*/ - lexiVtCount] = (node, context) => { ... };

        }
    }
}